package com.ray.test.mybaits;

import com.alibaba.fastjson.JSON;
import com.ray.test.proxy.MethodResult;
import com.ray.test.proxy.MockTestConfig;
import com.ray.test.util.AopTargetUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;

import java.lang.reflect.Method;
import java.sql.Statement;
import java.util.Map;
import java.util.Properties;

/**
 * @author bo shen
 * @Description: 拦截器
 * @Class: MybatisInterceptor
 * @Package com.ray.test.mybaits
 * @date 2020/4/3 11:02
 * @company <p>杭州传化陆鲸科技有限公司</p>
 * @updateRecord time(修改时间)  author(修改人)   desc(修改内容)
 */
@Intercepts({
        @Signature(method = "update", type = Executor.class, args = {MappedStatement.class, Object.class}),
        @Signature(method = "query", type = StatementHandler.class, args = {Statement.class, ResultHandler.class})
})
@Slf4j
public class MybatisInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        MockTestConfig config = MockTestConfig.get();
        Object target = invocation.getTarget();
        Method method = invocation.getMethod();
        MethodResult methodResult = new MethodResult(target.getClass(), method.getName(), config.integer.getAndIncrement(), null);
        Map<String, MethodResult> map = config.getMockData().getResults();
        log.info("数据库{}方法被调用,配置信息:{}", method.getName(), JSON.toJSONString(config));
        Object result = null;
        if (config != null && config.isMock() && config.isHasData()) {
            log.info("key:{}", methodResult.getKey());
            result = map.get(methodResult.getKey()).getResult();
        } else {
            try {
                log.info("执行正常的数据库操作");
                result = invocation.proceed();
                methodResult.setResult(result);
                config.getMockData().getResults().put(methodResult.getKey(), methodResult);
            } catch (Exception e) {
                log.info("调用服务异常", e);
                throw new RuntimeException("调用服务异常");
            }
        }
        log.info("{}方法被调用结果:{}", method.getName(), JSON.toJSONString(result));
        return result;
    }

    @Override
    public Object plugin(Object target) {
        // 调用插件
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
